package nl.infodation.emr.pricingservice.controller;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;

import nl.infodation.emr.pricingservice.data.PromotionConnectedSelection;
import nl.infodation.emr.psrefdata.entity.SalesSupport;
import nl.infodation.emr.utility.StringUtil;

import com.vaadin.data.util.BeanItem;

@SuppressWarnings({"deprecation", "rawtypes", "unchecked"})
public class PromotionConnectedSelectionController extends
		AbstractBaseController<Object, PromotionConnectedSelection, Integer> {

	public PromotionConnectedSelectionController() {
		setEntityManagerFactoryForRole();
	}

	@Override
	public long getTotalNumberItemByCriteria(PromotionConnectedSelection t) {
		long countResult = 0l;
		setEntityManagerFactoryForRolePopup(t.getBussinessLine());
		EntityManager entityManager = null;
		try {
			entityManager = EM_FACTORY.createEntityManager();
			entityManager.getTransaction().begin();
			queryString.setLength(0);
			final PromotionConnectedSelection p = (PromotionConnectedSelection) t;

			SalesSupport salesSupport = new SalesSupport();
			if (!StringUtil.isEmptyOrBlank(p.getCountryCode())) {
				salesSupport.setCountryCode(p.getCountryCode());
			}
			
			if (!StringUtil.isEmptyOrBlank(p.getChannelValue())) {
				salesSupport.setChannelValue(p.getChannelValue());
			}

			if (!StringUtil.isEmptyOrBlank(p.getSalesId())) {
				long salesId = 0L; // salesID = 0 if cannot convert to long
				try {
					salesId = Long.parseLong(p.getSalesId());
					salesSupport.setSalesId(salesId);
				} catch (NumberFormatException ex) {
					LOG.error(
							"Error converting salesId string type to long type: ",
							ex);
				}
			}

			buildSelectCount(salesSupport);
			buildQueryAndParams(salesSupport);

			if (StringUtil.isEmptyOrBlank(p.getSalesId())) {
				if (!queryString.toString().toLowerCase().contains("where")) {
					append(" WHERE ");
				} else {
					append(" AND ");
				}
				
				append(queryObjChar + "countryCode IS NOT NULL");
			}
			
			final TypedQuery<Long> query = entityManager.createQuery(queryString
					.toString(), Long.class);
			LOG.info("Executing the query \"{}\".", queryString);
			countResult = query.getSingleResult();
			entityManager.getTransaction().commit();

		} catch (IllegalStateException | IllegalAccessException ex) {
			LOG.error("Error reading getTotalNumberItemByCriteria.", ex);
			if (entityManager != null
					&& entityManager.getTransaction().isActive()) {
				LOG.info("Rolling back...");
				entityManager.getTransaction().rollback();
			}
		} finally {
			if (entityManager != null && entityManager.isOpen()) {
				entityManager.close();
			}
		}
		return countResult;
	}

	@Override
	public List getPaginationByCriteria(PromotionConnectedSelection object, int startPage,
			int pageSize) {
		final List<BeanItem> beans = new ArrayList<BeanItem>();
		setEntityManagerFactoryForRolePopup(object.getBussinessLine());
		EntityManager entityManager = null;
		try {
			entityManager = EM_FACTORY.createEntityManager();
			entityManager.getTransaction().begin();
			queryString.setLength(0);
			final PromotionConnectedSelection p = (PromotionConnectedSelection) object;

			SalesSupport salesSupport = new SalesSupport();
			if (!StringUtil.isEmptyOrBlank(p.getCountryCode())) {
				salesSupport.setCountryCode(p.getCountryCode());
			}
			
			if (!StringUtil.isEmptyOrBlank(p.getChannelValue())) {
				salesSupport.setChannelValue(p.getChannelValue());
			}

			if (!StringUtil.isEmptyOrBlank(p.getSalesId())) {
				long salesId = 0L; // salesID = 0 if cannot convert to long
				try {
					salesId = Long.parseLong(p.getSalesId());

				} catch (NumberFormatException ex) {
					LOG.error(
							"Error converting salesId string type to long type: ",
							ex);
				}
				salesSupport.setSalesId(salesId);
			}

			buildSelect(salesSupport);
			buildQueryAndParams(salesSupport);
			
			if (StringUtil.isEmptyOrBlank(p.getSalesId())) {
				if (!queryString.toString().toLowerCase().contains("where")) {
					append(" WHERE ");
				} else {
					append(" AND ");
				}
				
				append(queryObjChar + "countryCode IS NOT NULL");
			}
			
			final TypedQuery<SalesSupport> query = entityManager.createQuery(
					queryString.toString(), SalesSupport.class);
			if (startPage > 0) {
				query.setFirstResult((startPage - 1) * pageSize);
			} else {
				query.setFirstResult(1);
			}
			query.setMaxResults(pageSize);
			LOG.info("Executing the query \"{}\".", queryString);
			final List<SalesSupport> results = query.getResultList();
			if (!results.isEmpty()) {
				for (SalesSupport s : results) {
					PromotionConnectedSelection promotionConnectedSelection = 
							new PromotionConnectedSelection();
					promotionConnectedSelection.setChannelValue(s.getChannelValue());
					promotionConnectedSelection.setChannelCode(s.getChannelCode());
					promotionConnectedSelection.setSalesId(String.valueOf(s
							.getSalesId()));
					promotionConnectedSelection.setCountryCode(s.getCountryCode());
					
					beans.add(new BeanItem<PromotionConnectedSelection>(
							promotionConnectedSelection));
				}
			}

			entityManager.getTransaction().commit();

		} catch (IllegalStateException | IllegalAccessException ex) {
			LOG.error("Error reading getPaginationByCriteria.", ex);
			if (entityManager != null
					&& entityManager.getTransaction().isActive()) {
				LOG.info("Rolling back...");
				entityManager.getTransaction().rollback();
			}
		} finally {
			if (entityManager != null && entityManager.isOpen()) {
				entityManager.close();
			}
		}
		return beans;
	}
	
	
	@Override
	public List getPaginationList(int startPage, int pageSize) {
		return getPaginationByCriteria(new PromotionConnectedSelection(), startPage, pageSize);
	}

	@Override
	public long getTotalNumberItem() {
		return getTotalNumberItemByCriteria(new PromotionConnectedSelection());
	}

	@Override
	protected Boolean isObject(Field field) {
		return Boolean.FALSE;
	}

	@Override
	protected Object buildCriteria(PromotionConnectedSelection search) {
		return null;
	}

}